#pragma once

#include <iostream>
#include <functional>

#include "Socket.hpp"
#include "Log.hpp"
#include "Inet_Addr.hpp"
#include "Protocal.hpp"


using namespace SocketModule;
using namespace LogModule;

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>&)>;

class Service
{
public:
    Service(process_t process) 
        :_process(process)
    {}
    ~Service() {}
    void IoService(SockSPtr sock, Inet_Addr &addr)
    {
        std::string packagestreamqueue;
        while (true)
        {
            // 1、读取消息
            ssize_t n = sock->Recv(&packagestreamqueue);
            if (n <= 0)
            {
                LOG(FATAL, "client %s quit or recv error\n", addr.AddrStr().c_str());
                break;
            }
            // 2、解析有效载荷
            // 此时 recv 接收到的不一定是一个完整的报文
            std::string package = DeCode(packagestreamqueue);
            if(package.empty())// 如果 jsonstr 是空的 说明当前的数据流不是一个完整的报文
                continue;// 继续读取
            std::cout  << "package =>  " << package << std::endl;
            // 3、反序列化
            auto req = Factory::BuildRequest();
            req->Deserialize(package);
            // 4、业务处理
            auto resp = _process(req);
            // 5、序列化响应
            std::string jsonstr;
            resp->Serialize(&jsonstr);
            std::cout << "respjson: " << jsonstr << std::endl;
            // 6、添加报头
            jsonstr = EnCode(jsonstr);
            std::cout << "add header done, jsonstr is:\n" << jsonstr;
            // 7、发送回去
            n = sock->Send(jsonstr);
            if (n < 0)
            {
                LOG(FATAL, "send error\n");
                break;
            }
            std::cout << "==============================================" << std::endl;
        }

        
    }
private:
    process_t _process;
};
